package com.imooc.trading_system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.imooc.trading_system.enums.BizCodeEnum;
import com.imooc.trading_system.enums.order.OrderStatusEnum;
import com.imooc.trading_system.enums.order.OrderTypeEnum;
import com.imooc.trading_system.exception.BizException;
import com.imooc.trading_system.mapper.ProductMapper;
import com.imooc.trading_system.model.*;
import com.imooc.trading_system.mapper.OrderBaseMapper;
import com.imooc.trading_system.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.imooc.trading_system.utils.JsonData;
import com.imooc.trading_system.vo.address.GetAddressListRespVO;
import com.imooc.trading_system.vo.order.*;
import com.imooc.trading_system.vo.product.SearchProductListRespVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Feng zhaoxi
 * @since 2022-04-28
 */
@Service
public class OrderBaseServiceImpl implements OrderBaseService {
    @Resource
    private OrderBaseMapper orderBaseMapper;
    @Resource
    private ProductMapper productMapper;
    @Autowired
    private UserService userService;
    @Autowired
    private ProductService productService;
    @Autowired
    private AddressService addressService;
    @Autowired
    private WalletService walletService;

    /**
     * 创建订单
     *
     * @param createOrderReqVO
     * @return
     */
    @Override
    public JsonData createOrder(CreateOrderReqVO createOrderReqVO) {
        //登录用户-买家
        UserDO buyer = userService.getLoginUser();
        //通过产品id查询产品
        ProductDO product = productService.getProductInstance(createOrderReqVO.getProductId());
        //如果订单状态不为上线，则返回错误
        if (product.getProductStatus() != 1) {
            return JsonData.buildResult(BizCodeEnum.ORDER_OFFLINE);
        }

        UserDO seller = userService.getPublishUserInfo(product.getPublishUserId());
        if (buyer.getId().equals(seller.getId())) {
            return JsonData.buildResult(BizCodeEnum.CAN_NOT_BUY_SELF);
        }
        //如果库存小于1，就返回库存不足
        if (product.getProductStock() < 1) {
            return JsonData.buildResult(BizCodeEnum.STOCK_NOT_ENOUGH);
        }
        //如果购买的数量超过了库存，就返回库存不足
        if (product.getProductStock() - createOrderReqVO.getCount() < 0) {
            return JsonData.buildResult(BizCodeEnum.STOCK_NOT_ENOUGH);
        }
        //订单实例
        OrderBaseDO order = new OrderBaseDO();
        //产品id
        order.setProductId(createOrderReqVO.getProductId());
        //产品单价
        order.setProductPrice(product.getProductPrice());
        //购买产品的数量
        order.setBuyCount(createOrderReqVO.getCount());
        //订单总价
        order.setTotalPrice(order.getProductPrice().multiply(new BigDecimal(order.getBuyCount())));
        //卖家id
        order.setSellerUserId(product.getPublishUserId());
        //买家id
        order.setBuyerUserId(buyer.getId());
        //订单状态改为待支付
        order.setOrderStatus(OrderStatusEnum.TO_BE_PAID.getStatus());
        order.setOrderNo(String.valueOf(Calendar.getInstance().getTimeInMillis()) + (new Random()).nextInt(1000));
        //买家收货地址
        order.setBuyerAddress(createOrderReqVO.getBuyerAddress());
        //买家姓名
        order.setBuyerName(buyer.getUser());
        //买家手机号
        order.setBuyerPhoneNumber(buyer.getPhoneNumber());
        //卖家发货地址，默认使用卖家默认地址
        AddressDO sellerAddress = addressService.getSellerDefaultAddress(seller.getId());
        order.setSellerAddress(sellerAddress.getDetailAddress());
        //卖家姓名
        order.setSellerName(seller.getUser());
        order.setSellerPhoneNumber(seller.getPhoneNumber());
        //插入数据库order表
        int insert_rows = orderBaseMapper.insert(order);
        if (insert_rows != 1) {
            return JsonData.buildResult(BizCodeEnum.CREATE_ORDER_FAILED);
        }
        //更新产品的库存
        UpdateWrapper<ProductDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("product_id", product.getProductId());
        product.setProductStock(product.getProductStock() - createOrderReqVO.getCount());
        int update_row = productMapper.update(product, updateWrapper);
        if (update_row != 1) {
            return JsonData.buildResult(BizCodeEnum.CREATE_ORDER_FAILED);
        }
        return JsonData.buildSuccess();
    }

    /**
     * 获取我的订单
     *
     * @param getMyOrderReqVO
     * @return
     */
    @Override
    public JsonData getMyOrder(GetMyOrderReqVO getMyOrderReqVO) {
        UserDO userDO = userService.getLoginUser();
        int page = getMyOrderReqVO.getPage();
        int size = getMyOrderReqVO.getSize();
        if (page > 0 && size > 0) {
            PageHelper.startPage(page, size);
        }
        //买家订单
        if (getMyOrderReqVO.getOrderType() == OrderTypeEnum.BUYER_ORDER.getStatus()) {
            getMyOrderReqVO.setBuyerUserId(userDO.getId());
        }
        //卖家订单
        else if (getMyOrderReqVO.getOrderType() == OrderTypeEnum.SELLER_ORDER.getStatus()) {
            getMyOrderReqVO.setSellerUserId(userDO.getId());
        }
        List<OrderBaseDO> orderRespVOS = orderBaseMapper.getMyOrder(getMyOrderReqVO);

        List<GetMyOrderRespVO> getMyOrderRespVOList = orderRespVOS.stream().map(obj -> {
            GetMyOrderRespVO getMyOrderRespVO = new GetMyOrderRespVO();
            ProductDO productDO = productService.getProductInstance(obj.getProductId());
            getMyOrderRespVO.setProductCoverImg(productDO.getProductCoverImg());
            getMyOrderRespVO.setProductTitle(productDO.getProductTitle());
            UserDO sellerDO = userService.getPublishUserInfo(obj.getSellerUserId());
            getMyOrderRespVO.setPublishUserName(sellerDO.getUser());
            getMyOrderRespVO.setProductPrice(obj.getProductPrice());
            getMyOrderRespVO.setBuyCount(obj.getBuyCount());
            getMyOrderRespVO.setTotalPrice(obj.getTotalPrice());
            getMyOrderRespVO.setLogistics(obj.getLogistics());
            getMyOrderRespVO.setOrderStatus(obj.getOrderStatus());
            getMyOrderRespVO.setCreateTime(obj.getCreateTime());
            getMyOrderRespVO.setOrderNo(obj.getOrderNo());
            getMyOrderRespVO.setOrderId(obj.getOrderId());
            return getMyOrderRespVO;
        }).collect(Collectors.toList());
        PageInfo<GetMyOrderRespVO> pageInfo = new PageInfo<>(getMyOrderRespVOList);
        return JsonData.buildSuccess(pageInfo);
    }

    /**
     * 支付订单
     *
     * @param payReqVO
     * @return
     */
    @Override
    public JsonData toPay(PayReqVO payReqVO) {
        BigDecimal balance = walletService.getWalletBalance();
        if (balance.compareTo(payReqVO.getTotalPrice()) < 0) {
            return JsonData.buildResult(BizCodeEnum.BALANCE_NOT_ENOUGH);
        }
        //买家扣款
        walletService.deductions(payReqVO.getTotalPrice());
        OrderBaseDO orderBaseDO = orderBaseMapper.selectOne(new QueryWrapper<OrderBaseDO>()
                .eq("order_no", payReqVO.getOrderNo()));
        UpdateWrapper<OrderBaseDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_no", payReqVO.getOrderNo());
        //订单状态更改为已支付，待发货
        orderBaseDO.setOrderStatus(OrderStatusEnum.PAID_READY_FOR_DELIVERY.getStatus());
        orderBaseMapper.update(orderBaseDO, updateWrapper);
        return JsonData.buildSuccess();
    }

    /**
     * 确认收货
     *
     * @param confirmReqVO
     * @return
     */
    @Override
    public JsonData confirm(ConfirmReqVO confirmReqVO) {
        UserDO user = userService.getLoginUser();
        //查询订单
        OrderBaseDO order = orderBaseMapper.selectOne(new QueryWrapper<OrderBaseDO>()
                .eq("buyer_user_id", user.getId())
                .eq("order_no", confirmReqVO.getOrderNo()));
        if (order == null) {
            return JsonData.buildResult(BizCodeEnum.NO_ORDER);
        }
        //更新订单状态为待评价
        UpdateWrapper<OrderBaseDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_no", confirmReqVO.getOrderNo());
        order.setOrderStatus(OrderStatusEnum.TO_EVALUATE.getStatus());
        orderBaseMapper.update(order, updateWrapper);
        return JsonData.buildSuccess();
    }

    /**
     * 买家给卖家评价
     *
     * @param evaluationReqVO
     * @return
     */
    @Override
    public JsonData evaluation(EvaluationReqVO evaluationReqVO) {
        UserDO user = userService.getLoginUser();
        //查询订单
        OrderBaseDO order = orderBaseMapper.selectOne(new QueryWrapper<OrderBaseDO>()
                .eq("buyer_user_id", user.getId())
                .eq("order_no", evaluationReqVO.getOrderNo()));
        if (order == null) {
            return JsonData.buildResult(BizCodeEnum.NO_ORDER);
        }
        //买家给卖家的评价更新
        UpdateWrapper<OrderBaseDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_no", evaluationReqVO.getOrderNo());
        order.setBuyerToSellerEvaluation(String.valueOf(evaluationReqVO.getEvaluation()));
        //更新订单状态为完成
        order.setOrderStatus(OrderStatusEnum.FINISHED.getStatus());
        orderBaseMapper.update(order, updateWrapper);
        return JsonData.buildSuccess();
    }

    /**
     * 卖家发货
     *
     * @param deliverGoodsReqVO
     * @return
     */
    @Override
    public JsonData deliverGoods(DeliverGoodsReqVO deliverGoodsReqVO) {
        UserDO user = userService.getLoginUser();
        //查询订单
        OrderBaseDO order = orderBaseMapper.selectOne(new QueryWrapper<OrderBaseDO>()
                .eq("seller_user_id", user.getId())
                .eq("order_no", deliverGoodsReqVO.getOrderNo()));
        if (order == null) {
            return JsonData.buildResult(BizCodeEnum.NO_ORDER);
        }
        UpdateWrapper<OrderBaseDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_no", deliverGoodsReqVO.getOrderNo());
        //物流公司
        order.setLogistics(deliverGoodsReqVO.getLogistics());
        //物流单号
        order.setLogisticsNo(deliverGoodsReqVO.getLogisticsNo());
        //设置订单状态为已发货
        order.setOrderStatus(OrderStatusEnum.HAS_BEEN_SHIPPED.getStatus());
        orderBaseMapper.update(order, updateWrapper);
        //更新状态为待确认
        buyerConfirm(deliverGoodsReqVO.getOrderNo());
        return JsonData.buildSuccess();
    }

    /**
     * 更新状态为运输中
     *
     * @param orderNo
     */
    @Override
    public void inTransit(String orderNo) {
        UserDO user = userService.getLoginUser();
        //查询订单
        OrderBaseDO order = orderBaseMapper.selectOne(new QueryWrapper<OrderBaseDO>()
                .eq("seller_user_id", user.getId())
                .eq("order_no", orderNo));
        if (order == null) {
            throw new BizException(BizCodeEnum.NO_ORDER);
        }
        UpdateWrapper<OrderBaseDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_no", orderNo);
        order.setOrderStatus(OrderStatusEnum.IN_TRANSIT.getStatus());
        orderBaseMapper.update(order, updateWrapper);
    }

    /**
     * 更新状态为已送达
     *
     * @param orderNo
     */
    @Override
    public void haveArrived(String orderNo) {
        UserDO user = userService.getLoginUser();
        //查询订单
        OrderBaseDO order = orderBaseMapper.selectOne(new QueryWrapper<OrderBaseDO>()
                .eq("seller_user_id", user.getId())
                .eq("order_no", orderNo));
        if (order == null) {
            throw new BizException(BizCodeEnum.NO_ORDER);
        }
        UpdateWrapper<OrderBaseDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_no", orderNo);
        order.setOrderStatus(OrderStatusEnum.HAVE_ARRIVED.getStatus());
        orderBaseMapper.update(order, updateWrapper);
    }

    /**
     * 更新状态为待确认
     *
     * @param orderNo
     */
    @Override
    public void buyerConfirm(String orderNo) {
        UserDO user = userService.getLoginUser();
        //查询订单
        OrderBaseDO order = orderBaseMapper.selectOne(new QueryWrapper<OrderBaseDO>()
                .eq("seller_user_id", user.getId())
                .eq("order_no", orderNo));
        if (order == null) {
            throw new BizException(BizCodeEnum.NO_ORDER);
        }
        UpdateWrapper<OrderBaseDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_no", orderNo);
        order.setOrderStatus(OrderStatusEnum.BUYER_CONFIRM.getStatus());
        orderBaseMapper.update(order, updateWrapper);
    }

    /**
     * 获取订单状态的个数，包括待付款、待发货、待确认、待评价
     *
     * @return
     */
    @Override
    public JsonData getOrderStatusCount() {
        UserDO userDO = userService.getLoginUser();
        int toPayCount = 0;
        int toSendCount = 0;
        int toConfirmCount = 0;
        int toEvaluationCount = 0;
        //作为买家，待付款个数
        List<OrderBaseDO> toPayCountBuyer = orderBaseMapper.selectList(new QueryWrapper<OrderBaseDO>()
                .eq("buyer_user_id", userDO.getId())
                .eq("order_status", OrderStatusEnum.TO_BE_PAID.getStatus()));
        toPayCount = toPayCount + toPayCountBuyer.size();
        //作为买家，待发货个数
        List<OrderBaseDO> toSendCountBuyer = orderBaseMapper.selectList(new QueryWrapper<OrderBaseDO>()
                .eq("buyer_user_id", userDO.getId())
                .eq("order_status", OrderStatusEnum.PAID_READY_FOR_DELIVERY.getStatus()));
        toSendCount = toSendCount + toSendCountBuyer.size();
        //作为买家，待确认个数
        List<OrderBaseDO> toConfirmCountBuyer = orderBaseMapper.selectList(new QueryWrapper<OrderBaseDO>()
                .eq("buyer_user_id", userDO.getId())
                .eq("order_status", OrderStatusEnum.BUYER_CONFIRM.getStatus()));
        toConfirmCount = toConfirmCount + toConfirmCountBuyer.size();
        //作为买家，待评价个数
        List<OrderBaseDO> toEvaluationCountBuyer = orderBaseMapper.selectList(new QueryWrapper<OrderBaseDO>()
                .eq("buyer_user_id", userDO.getId())
                .eq("order_status", OrderStatusEnum.TO_EVALUATE.getStatus()));
        toEvaluationCount = toEvaluationCount + toEvaluationCountBuyer.size();
        //作为卖家，待付款个数
        List<OrderBaseDO> toPayCountSeller = orderBaseMapper.selectList(new QueryWrapper<OrderBaseDO>()
                .eq("seller_user_id", userDO.getId())
                .eq("order_status", OrderStatusEnum.TO_BE_PAID.getStatus()));
        toPayCount = toPayCount + toPayCountSeller.size();
        //作为卖家，待发货个数
        List<OrderBaseDO> toSendCountSeller = orderBaseMapper.selectList(new QueryWrapper<OrderBaseDO>()
                .eq("seller_user_id", userDO.getId())
                .eq("order_status", OrderStatusEnum.PAID_READY_FOR_DELIVERY.getStatus()));
        toSendCount = toSendCount + toSendCountSeller.size();
        //作为卖家，待确认个数
        List<OrderBaseDO> toConfirmCountSeller = orderBaseMapper.selectList(new QueryWrapper<OrderBaseDO>()
                .eq("seller_user_id", userDO.getId())
                .eq("order_status", OrderStatusEnum.BUYER_CONFIRM.getStatus()));
        toConfirmCount = toConfirmCount + toConfirmCountSeller.size();
        //作为卖家，待评价个数
        List<OrderBaseDO> toEvaluationCountSeller = orderBaseMapper.selectList(new QueryWrapper<OrderBaseDO>()
                .eq("seller_user_id", userDO.getId())
                .eq("order_status", OrderStatusEnum.TO_EVALUATE.getStatus()));
        toEvaluationCount = toEvaluationCount + toEvaluationCountSeller.size();
        GetOrderStatusCountRespVO getOrderStatusCountRespVO = new GetOrderStatusCountRespVO();
        getOrderStatusCountRespVO.setToPay(toPayCount);
        getOrderStatusCountRespVO.setToSend(toSendCount);
        getOrderStatusCountRespVO.setToConfirm(toConfirmCount);
        getOrderStatusCountRespVO.setToEvaluation(toEvaluationCount);
        return JsonData.buildSuccess(getOrderStatusCountRespVO);
    }
}
